repo: Ensure we set mode for bare-user files before xattrs
authorColin Walters <walters@verbum.org>
Tue, 12 Jul 2016 13:43:32 +0000 (09:43 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Tue, 12 Jul 2016 14:09:37 +0000 (14:09 +0000)
When trying to switch ostree to `O_TMPFILE`, I hit the fact that
by default it uses mode `000`.  It still works to write to the
open fd of course, but it *doesn't* work to set xattrs because
that code path for some reason in the kernel checks the mode bits.

This only broke for bare-user repos where we tried to set the xattr
before calling `fchmod()`, so just invert those two operations.

Closes: #391
Approved by: jlebon

src/libostree/ostree-repo-commit.c

index 662ee21e7e959f92422ab7766ee908b11d135af1..fcfe487ab225af57a403c5d24dcfc391179be8bb 100644 (file)
@@ -240,15 +240,13 @@ commit_loose_object_trusted (OstreeRepo        *self,
 
       if (objtype == OSTREE_OBJECT_TYPE_FILE && self->mode == OSTREE_REPO_MODE_BARE_USER)
         {
-          if (!write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
-            goto out;
-
           if (!object_is_symlink)
             {
               /* We need to apply at least some mode bits, because the repo file was created
                  with mode 644, and we need e.g. exec bits to be right when we do a user-mode
                  checkout. To make this work we apply all user bits and the read bits for
-                 group/other */
+                 group/other.  Furthermore, setting user xattrs requires write access, so
+                 this makes sure it's at least writable by us.  (O_TMPFILE uses mode 0 by default) */
               do
                 res = fchmod (fd, mode | 0744);
               while (G_UNLIKELY (res == -1 && errno == EINTR));
@@ -258,6 +256,9 @@ commit_loose_object_trusted (OstreeRepo        *self,
                   goto out;
                 }
             }
+
+          if (!write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
+            goto out;
         }
 
       if (objtype == OSTREE_OBJECT_TYPE_FILE && (self->mode == OSTREE_REPO_MODE_BARE ||